/*     */ package com.zimbra.cs.mailclient.imap;
/*     */ 
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.cs.mailclient.CommandFailedException;
/*     */ import com.zimbra.cs.mailclient.MailConfig;
/*     */ import com.zimbra.cs.mailclient.MailConnection;
/*     */ import com.zimbra.cs.mailclient.MailConnection.State;
/*     */ import com.zimbra.cs.mailclient.MailException;
/*     */ import com.zimbra.cs.mailclient.MailInputStream;
/*     */ import com.zimbra.cs.mailclient.MailOutputStream;
/*     */ import com.zimbra.cs.mailclient.ParseException;
/*     */ import com.zimbra.cs.mailclient.auth.Authenticator;
/*     */ import com.zimbra.cs.mailclient.util.Ascii;
/*     */ import java.io.IOException;
/*     */ import java.io.InputStream;
/*     */ import java.io.OutputStream;
/*     */ import java.net.SocketTimeoutException;
/*     */ import java.util.ArrayList;
/*     */ import java.util.Arrays;
/*     */ import java.util.Collection;
/*     */ import java.util.Date;
/*     */ import java.util.Formatter;
/*     */ import java.util.HashMap;
/*     */ import java.util.List;
/*     */ import java.util.Map;
/*     */ import java.util.concurrent.atomic.AtomicInteger;
/*     */ import org.apache.commons.codec.binary.Base64;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public final class ImapConnection
/*     */   extends MailConnection
/*     */ {
/*     */   private ImapCapabilities capabilities;
/*     */   private MailboxInfo mailbox;
/*     */   private ImapRequest request;
/*     */   private DataHandler dataHandler;
/*     */   private Character delimiter;
/*  51 */   private final AtomicInteger tagCount = new AtomicInteger();
/*     */   private static final String TAG_FORMAT = "C%02d";
/*     */   
/*     */   public ImapConnection(ImapConfig config)
/*     */   {
/*  56 */     super(config);
/*     */   }
/*     */   
/*     */   public void setDataHandler(DataHandler handler) {
/*  60 */     this.dataHandler = handler;
/*     */   }
/*     */   
/*     */   public DataHandler getDataHandler() {
/*  64 */     return this.dataHandler;
/*     */   }
/*     */   
/*     */   protected MailInputStream newMailInputStream(InputStream is)
/*     */   {
/*  69 */     if (getLogger().isTraceEnabled()) {
/*  70 */       return new ImapInputStream(is, this, getLogger());
/*     */     }
/*  72 */     return new ImapInputStream(is, this);
/*     */   }
/*     */   
/*     */ 
/*     */   protected MailOutputStream newMailOutputStream(OutputStream os)
/*     */   {
/*  78 */     if (getLogger().isTraceEnabled()) {
/*  79 */       return new ImapOutputStream(os, getLogger());
/*     */     }
/*  81 */     return new ImapOutputStream(os);
/*     */   }
/*     */   
/*     */   protected void processGreeting()
/*     */     throws IOException
/*     */   {
/*  87 */     ImapResponse res = readResponse();
/*  88 */     if (res.isUntagged()) {
/*  89 */       this.greeting = res.getResponseText().getText();
/*  90 */       switch (res.getCCode()) {
/*     */       case BYE: 
/*  92 */         throw new MailException(this.greeting);
/*     */       case PREAUTH: 
/*     */       case OK: 
/*  95 */         setState(res.isOK() ? MailConnection.State.NOT_AUTHENTICATED : MailConnection.State.AUTHENTICATED);
/*     */         
/*  97 */         ResponseText rt = res.getResponseText();
/*  98 */         if (CAtom.CAPABILITY.atom().equals(rt.getCode())) {
/*  99 */           this.capabilities = ((ImapCapabilities)rt.getData());
/*     */         } else {
/* 101 */           capability();
/*     */         }
/* 103 */         return;
/*     */       }
/*     */     }
/* 106 */     throw new MailException("Expected server greeting but got: " + res);
/*     */   }
/*     */   
/*     */   protected void sendLogin(String user, String pass) throws IOException
/*     */   {
/* 111 */     newRequest(CAtom.LOGIN, new Object[] { ImapData.asAString(user), ImapData.asAString(pass) }).sendCheckStatus();
/*     */   }
/*     */   
/*     */   public synchronized void logout() throws IOException
/*     */   {
/* 116 */     if (isShutdown()) return;
/* 117 */     if (this.request != null) {
/* 118 */       throw new IllegalStateException("Request pending");
/*     */     }
/* 120 */     setState(MailConnection.State.LOGOUT);
/*     */     try {
/* 122 */       newRequest(CAtom.LOGOUT, new Object[0]).sendCheckStatus();
/*     */     } catch (CommandFailedException e) {
/* 124 */       getLogger().warn("Logout failed, force closing connection", e);
/* 125 */       close();
/*     */     }
/*     */   }
/*     */   
/*     */   protected void sendAuthenticate(boolean ir) throws IOException
/*     */   {
/* 131 */     ImapRequest req = newRequest(CAtom.AUTHENTICATE, new Object[] { this.authenticator.getMechanism() });
/*     */     
/* 133 */     if (ir) {
/* 134 */       byte[] response = this.authenticator.getInitialResponse();
/* 135 */       req.addParam(Ascii.toString(Base64.encodeBase64(response)));
/*     */     }
/* 137 */     req.sendCheckStatus();
/*     */   }
/*     */   
/*     */   protected void sendStartTls() throws IOException
/*     */   {
/* 142 */     newRequest(CAtom.STARTTLS, new Object[0]).sendCheckStatus();
/*     */   }
/*     */   
/*     */   public ImapCapabilities capability() throws IOException {
/* 146 */     newRequest(CAtom.CAPABILITY, new Object[0]).sendCheckStatus();
/* 147 */     return this.capabilities;
/*     */   }
/*     */   
/*     */   public void noop() throws IOException {
/* 151 */     newRequest(CAtom.NOOP, new Object[0]).sendCheckStatus();
/*     */   }
/*     */   
/*     */   public void noop(ResponseHandler handler) throws IOException {
/* 155 */     ImapRequest req = newRequest(CAtom.NOOP, new Object[0]);
/* 156 */     req.setResponseHandler(handler);
/* 157 */     req.sendCheckStatus();
/*     */   }
/*     */   
/*     */   public void idle(ResponseHandler handler) throws IOException {
/* 161 */     ImapRequest req = newRequest(CAtom.IDLE, new Object[0]);
/* 162 */     req.setResponseHandler(handler);
/* 163 */     ImapResponse res = req.send();
/* 164 */     if (res != null) {
/* 165 */       if (res.isOK()) {
/* 166 */         throw new MailException("Expected IDLE continuation but got final response");
/*     */       }
/*     */       
/* 169 */       req.checkStatus(res);
/*     */     }
/*     */   }
/*     */   
/*     */   public void check() throws IOException {
/* 174 */     newRequest(CAtom.CHECK, new Object[0]).sendCheckStatus();
/*     */   }
/*     */   
/*     */   public void xatom(String cmd, Object... params) throws IOException {
/* 178 */     newRequest(cmd, params).sendCheckStatus();
/*     */   }
/*     */   
/*     */   public IDInfo id(IDInfo info) throws IOException {
/* 182 */     ImapRequest req = newRequest(CAtom.ID, new Object[] { info == null ? CAtom.NIL : info });
/* 183 */     List<IDInfo> results = new ArrayList(1);
/* 184 */     req.setResponseHandler(new BasicResponseHandler(CAtom.ID, results));
/* 185 */     req.sendCheckStatus();
/* 186 */     return results.isEmpty() ? new IDInfo() : (IDInfo)results.get(0);
/*     */   }
/*     */   
/*     */   public synchronized boolean isSelected(String name) {
/* 190 */     return (this.mailbox != null) && (this.mailbox.getName().equals(name));
/*     */   }
/*     */   
/*     */   public synchronized MailboxInfo select(String name) throws IOException {
/* 194 */     this.mailbox = doSelectOrExamine(CAtom.SELECT, name);
/* 195 */     setState(MailConnection.State.SELECTED);
/* 196 */     return getMailboxInfo();
/*     */   }
/*     */   
/*     */   public MailboxInfo examine(String name) throws IOException {
/* 200 */     return doSelectOrExamine(CAtom.EXAMINE, name);
/*     */   }
/*     */   
/*     */   private MailboxInfo doSelectOrExamine(CAtom cmd, String name) throws IOException {
/* 204 */     MailboxInfo mbox = new MailboxInfo(name);
/* 205 */     ImapRequest req = newRequest(cmd, new Object[] { new MailboxName(name) });
/* 206 */     req.setResponseHandler(mbox);
/* 207 */     mbox.handleResponse(req.sendCheckStatus());
/* 208 */     return mbox;
/*     */   }
/*     */   
/*     */   public void create(String name) throws IOException {
/* 212 */     newRequest(CAtom.CREATE, new Object[] { new MailboxName(name) }).sendCheckStatus();
/*     */   }
/*     */   
/*     */   public void delete(String name) throws IOException {
/* 216 */     newRequest(CAtom.DELETE, new Object[] { new MailboxName(name) }).sendCheckStatus();
/*     */   }
/*     */   
/*     */   public void rename(String from, String to) throws IOException {
/* 220 */     newRequest(CAtom.RENAME, new Object[] { new MailboxName(from), new MailboxName(to) }).sendCheckStatus();
/*     */   }
/*     */   
/*     */   public void subscribe(String name) throws IOException
/*     */   {
/* 225 */     newRequest(CAtom.SUBSCRIBE, new Object[] { new MailboxName(name) }).sendCheckStatus();
/*     */   }
/*     */   
/*     */   public void unsubscribe(String name) throws IOException {
/* 229 */     newRequest(CAtom.UNSUBSCRIBE, new Object[] { new MailboxName(name) }).sendCheckStatus();
/*     */   }
/*     */   
/*     */   public AppendResult append(String mbox, Flags flags, Date date, Literal data) throws IOException
/*     */   {
/* 234 */     return append(mbox, new AppendMessage[] { new AppendMessage(flags, date, new Object[] { data }) });
/*     */   }
/*     */   
/*     */   public AppendResult append(String mbox, AppendMessage... msgs) throws IOException {
/* 238 */     return append(mbox, Arrays.asList(msgs));
/*     */   }
/*     */   
/*     */   public AppendResult append(String mbox, Collection<AppendMessage> msgs) throws IOException
/*     */   {
/* 243 */     ImapRequest req = newRequest(CAtom.APPEND, new Object[] { new MailboxName(mbox) });
/* 244 */     for (AppendMessage msg : msgs) {
/* 245 */       req.addParam(msg);
/*     */     }
/* 247 */     ImapResponse res = req.sendCheckStatus();
/* 248 */     ResponseText rt = res.getResponseText();
/* 249 */     return rt.getCCode() == CAtom.APPENDUID ? (AppendResult)rt.getData() : null;
/*     */   }
/*     */   
/*     */   public void expunge() throws IOException {
/* 253 */     newRequest(CAtom.EXPUNGE, new Object[0]).sendCheckStatus();
/*     */   }
/*     */   
/*     */   public void uidExpunge(String seq) throws IOException {
/* 257 */     newUidRequest(CAtom.EXPUNGE, new Object[] { seq }).sendCheckStatus();
/*     */   }
/*     */   
/*     */   public synchronized void close_mailbox() throws IOException {
/* 261 */     newRequest(CAtom.CLOSE, new Object[0]).sendCheckStatus();
/* 262 */     this.mailbox = null;
/* 263 */     setState(MailConnection.State.AUTHENTICATED);
/*     */   }
/*     */   
/*     */   public synchronized void unselect() throws IOException {
/* 267 */     newRequest(CAtom.UNSELECT, new Object[0]).sendCheckStatus();
/* 268 */     this.mailbox = null;
/* 269 */     setState(MailConnection.State.AUTHENTICATED);
/*     */   }
/*     */   
/*     */   public MailboxInfo status(String name, Object... params) throws IOException {
/* 273 */     ImapRequest req = newRequest(CAtom.STATUS, new Object[] { new MailboxName(name), params });
/* 274 */     List<MailboxInfo> results = new ArrayList(1);
/* 275 */     req.setResponseHandler(new BasicResponseHandler(CAtom.STATUS, results));
/* 276 */     req.sendCheckStatus();
/* 277 */     if (results.isEmpty()) {
/* 278 */       throw new MailException("Missing STATUS response data");
/*     */     }
/* 280 */     return (MailboxInfo)results.get(0);
/*     */   }
/*     */   
/*     */   public List<ListData> list(String ref, String mbox) throws IOException {
/* 284 */     return doList(CAtom.LIST, ref, mbox);
/*     */   }
/*     */   
/*     */   public List<ListData> lsub(String ref, String mbox) throws IOException {
/* 288 */     return doList(CAtom.LSUB, ref, mbox);
/*     */   }
/*     */   
/*     */   public boolean exists(String mbox) throws IOException {
/* 292 */     return !list("", mbox).isEmpty();
/*     */   }
/*     */   
/*     */   private List<ListData> doList(CAtom cmd, String ref, String mbox) throws IOException
/*     */   {
/* 297 */     ImapRequest req = newRequest(cmd, new Object[] { new MailboxName(ref), new MailboxName(mbox) });
/* 298 */     List<ListData> results = new ArrayList();
/* 299 */     req.setResponseHandler(new BasicResponseHandler(CAtom.LIST.atom(), results));
/* 300 */     req.sendCheckStatus();
/* 301 */     return results;
/*     */   }
/*     */   
/*     */   public char getDelimiter() throws IOException {
/* 305 */     if (this.delimiter == null) {
/* 306 */       List<ListData> ld = list("", "");
/* 307 */       this.delimiter = Character.valueOf(ld.isEmpty() ? '\000' : ((ListData)ld.get(0)).getDelimiter());
/*     */     }
/* 309 */     return this.delimiter.charValue();
/*     */   }
/*     */   
/*     */   public CopyResult copy(String seq, String mbox) throws IOException {
/* 313 */     ImapRequest req = newRequest(CAtom.COPY, new Object[] { seq, new MailboxName(mbox) });
/* 314 */     ResponseText rt = req.sendCheckStatus().getResponseText();
/* 315 */     return rt.getCCode() == CAtom.COPYUID ? (CopyResult)rt.getData() : null;
/*     */   }
/*     */   
/*     */   public CopyResult uidCopy(String seq, String mbox) throws IOException {
/* 319 */     ImapRequest req = newUidRequest(CAtom.COPY, new Object[] { seq, new MailboxName(mbox) });
/* 320 */     ResponseText rt = req.sendCheckStatus().getResponseText();
/* 321 */     return rt.getCCode() == CAtom.COPYUID ? (CopyResult)rt.getData() : null;
/*     */   }
/*     */   
/*     */   public void fetch(String seq, Object param, ResponseHandler handler) throws IOException
/*     */   {
/* 326 */     fetch(CAtom.FETCH.name(), seq, param, handler);
/*     */   }
/*     */   
/*     */   public void uidFetch(String seq, Object param, ResponseHandler handler) throws IOException
/*     */   {
/* 331 */     ImapRequest req = newUidRequest(CAtom.FETCH, new Object[] { seq, param });
/* 332 */     req.setResponseHandler(handler);
/* 333 */     req.sendCheckStatus();
/*     */   }
/*     */   
/*     */   private void fetch(String cmd, String seq, Object param, ResponseHandler handler) throws IOException
/*     */   {
/* 338 */     ImapRequest req = newRequest(cmd, new Object[] { seq, param });
/* 339 */     req.setResponseHandler(handler);
/* 340 */     req.sendCheckStatus();
/*     */   }
/*     */   
/*     */   public List<Long> getUids(String seq) throws IOException {
/* 344 */     final List<Long> uids = new ArrayList();
/* 345 */     uidFetch(seq, "UID", new FetchResponseHandler()
/*     */     {
/*     */       public void handleFetchResponse(MessageData md) {
/* 348 */         uids.add(Long.valueOf(md.getUid()));
/*     */       }
/* 350 */     });
/* 351 */     return uids;
/*     */   }
/*     */   
/*     */   public Map<Long, MessageData> fetch(String seq, Object param) throws IOException
/*     */   {
/* 356 */     final Map<Long, MessageData> results = new HashMap();
/* 357 */     fetch(seq, param, new FetchResponseHandler(false)
/*     */     {
/*     */       public void handleFetchResponse(MessageData md) {
/* 360 */         long msgno = md.getMsgno();
/* 361 */         if (msgno > 0L) {
/* 362 */           MessageData omd = (MessageData)results.get(Long.valueOf(msgno));
/* 363 */           if (omd != null) {
/* 364 */             omd.addFields(md);
/*     */           } else {
/* 366 */             results.put(Long.valueOf(msgno), md);
/*     */           }
/*     */         }
/*     */       }
/* 370 */     });
/* 371 */     return results;
/*     */   }
/*     */   
/*     */   public MessageData fetch(long msgno, Object param) throws IOException {
/* 375 */     return (MessageData)fetch(String.valueOf(msgno), param).get(Long.valueOf(msgno));
/*     */   }
/*     */   
/*     */   public Map<Long, MessageData> uidFetch(String seq, Object param) throws IOException
/*     */   {
/* 380 */     final Map<Long, MessageData> results = new HashMap();
/* 381 */     uidFetch(seq, param, new FetchResponseHandler(false)
/*     */     {
/*     */       public void handleFetchResponse(MessageData md) {
/* 384 */         long uid = md.getUid();
/* 385 */         if (uid > 0L) {
/* 386 */           MessageData omd = (MessageData)results.get(Long.valueOf(uid));
/* 387 */           if (omd != null) {
/* 388 */             omd.addFields(md);
/*     */           } else {
/* 390 */             results.put(Long.valueOf(uid), md);
/*     */           }
/*     */         }
/*     */       }
/* 394 */     });
/* 395 */     return results;
/*     */   }
/*     */   
/*     */   public MessageData uidFetch(long uid, Object param) throws IOException {
/* 399 */     return (MessageData)uidFetch(String.valueOf(uid), param).get(Long.valueOf(uid));
/*     */   }
/*     */   
/*     */   public List<Long> search(Object... params) throws IOException {
/* 403 */     return doSearch(CAtom.SEARCH.name(), params);
/*     */   }
/*     */   
/*     */   public List<Long> uidSearch(Object... params) throws IOException {
/* 407 */     return doSearch("UID SEARCH", params);
/*     */   }
/*     */   
/*     */   private List<Long> doSearch(String cmd, Object... params) throws IOException
/*     */   {
/* 412 */     final List<Long> results = new ArrayList();
/* 413 */     ImapRequest req = newRequest(cmd, params);
/* 414 */     req.setResponseHandler(new ResponseHandler()
/*     */     {
/*     */       public void handleResponse(ImapResponse res) {
/* 417 */         if (res.getCCode() == CAtom.SEARCH) {
/* 418 */           results.addAll((List)res.getData());
/*     */         }
/*     */       }
/* 421 */     });
/* 422 */     req.sendCheckStatus();
/* 423 */     return results;
/*     */   }
/*     */   
/*     */   public void store(String seq, String item, Object flags) throws IOException {
/* 427 */     store(seq, item, flags, null);
/*     */   }
/*     */   
/*     */   public void store(String seq, String item, Object flags, ResponseHandler handler) throws IOException
/*     */   {
/* 432 */     ImapRequest req = newRequest(CAtom.STORE, new Object[] { seq, item, flags });
/* 433 */     req.setResponseHandler(handler);
/* 434 */     req.sendCheckStatus();
/*     */   }
/*     */   
/*     */   public void uidStore(String seq, String item, Object flags) throws IOException
/*     */   {
/* 439 */     uidStore(seq, item, flags, null);
/*     */   }
/*     */   
/*     */   public void uidStore(String seq, String item, Object flags, ResponseHandler handler) throws IOException
/*     */   {
/* 444 */     ImapRequest req = newUidRequest(CAtom.STORE, new Object[] { seq, item, flags });
/* 445 */     req.setResponseHandler(handler);
/* 446 */     req.sendCheckStatus();
/*     */   }
/*     */   
/*     */   public ImapRequest newRequest(CAtom cmd, Object... params) {
/* 450 */     return new ImapRequest(this, cmd.atom(), params);
/*     */   }
/*     */   
/*     */   public ImapRequest newRequest(Atom cmd, Object... params) {
/* 454 */     return new ImapRequest(this, cmd, params);
/*     */   }
/*     */   
/*     */   public ImapRequest newRequest(String cmd, Object... params) {
/* 458 */     return new ImapRequest(this, new Atom(cmd), params);
/*     */   }
/*     */   
/*     */   public ImapRequest newUidRequest(CAtom cmd, Object... params) {
/* 462 */     return newRequest("UID " + cmd.toString(), params);
/*     */   }
/*     */   
/*     */   public ImapCapabilities getCapabilities()
/*     */   {
/* 467 */     return this.capabilities;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   public MailboxInfo getMailboxInfo()
/*     */   {
/* 474 */     return this.mailbox != null ? new MailboxInfo(this.mailbox) : null;
/*     */   }
/*     */   
/*     */   public boolean hasCapability(String cap) {
/* 478 */     return (this.capabilities != null) && (this.capabilities.hasCapability(cap));
/*     */   }
/*     */   
/*     */   public boolean hasIdle() {
/* 482 */     return hasCapability("IDLE");
/*     */   }
/*     */   
/*     */   public boolean hasUnselect() {
/* 486 */     return hasCapability("UNSELECT");
/*     */   }
/*     */   
/*     */   public boolean hasMechanism(String method) {
/* 490 */     return hasCapability("AUTH=" + method);
/*     */   }
/*     */   
/*     */   public boolean hasUidPlus() {
/* 494 */     return hasCapability("UIDPLUS");
/*     */   }
/*     */   
/*     */   /* Error */
/*     */   synchronized ImapResponse sendRequest(ImapRequest req)
/*     */     throws IOException
/*     */   {
/*     */     // Byte code:
/*     */     //   0: aload_0
/*     */     //   1: invokevirtual 177	com/zimbra/cs/mailclient/imap/ImapConnection:isClosed	()Z
/*     */     //   4: ifeq +13 -> 17
/*     */     //   7: new 178	java/io/IOException
/*     */     //   10: dup
/*     */     //   11: ldc -77
/*     */     //   13: invokespecial 180	java/io/IOException:<init>	(Ljava/lang/String;)V
/*     */     //   16: athrow
/*     */     //   17: aload_0
/*     */     //   18: getfield 49	com/zimbra/cs/mailclient/imap/ImapConnection:request	Lcom/zimbra/cs/mailclient/imap/ImapRequest;
/*     */     //   21: ifnull +13 -> 34
/*     */     //   24: new 50	java/lang/IllegalStateException
/*     */     //   27: dup
/*     */     //   28: ldc -75
/*     */     //   30: invokespecial 52	java/lang/IllegalStateException:<init>	(Ljava/lang/String;)V
/*     */     //   33: athrow
/*     */     //   34: aload_1
/*     */     //   35: invokevirtual 182	com/zimbra/cs/mailclient/imap/ImapRequest:isIdle	()Z
/*     */     //   38: ifeq +9 -> 47
/*     */     //   41: aload_0
/*     */     //   42: aload_1
/*     */     //   43: invokespecial 183	com/zimbra/cs/mailclient/imap/ImapConnection:sendIdle	(Lcom/zimbra/cs/mailclient/imap/ImapRequest;)Lcom/zimbra/cs/mailclient/imap/ImapResponse;
/*     */     //   46: areturn
/*     */     //   47: aload_0
/*     */     //   48: aload_1
/*     */     //   49: putfield 49	com/zimbra/cs/mailclient/imap/ImapConnection:request	Lcom/zimbra/cs/mailclient/imap/ImapRequest;
/*     */     //   52: aload_1
/*     */     //   53: aload_0
/*     */     //   54: invokespecial 184	com/zimbra/cs/mailclient/imap/ImapConnection:getImapOutputStream	()Lcom/zimbra/cs/mailclient/imap/ImapOutputStream;
/*     */     //   57: invokevirtual 185	com/zimbra/cs/mailclient/imap/ImapRequest:write	(Lcom/zimbra/cs/mailclient/imap/ImapOutputStream;)V
/*     */     //   60: goto +16 -> 76
/*     */     //   63: astore_2
/*     */     //   64: aload_2
/*     */     //   65: getfield 187	com/zimbra/cs/mailclient/imap/ImapConnection$LiteralException:res	Lcom/zimbra/cs/mailclient/imap/ImapResponse;
/*     */     //   68: astore_3
/*     */     //   69: aload_0
/*     */     //   70: aconst_null
/*     */     //   71: putfield 49	com/zimbra/cs/mailclient/imap/ImapConnection:request	Lcom/zimbra/cs/mailclient/imap/ImapRequest;
/*     */     //   74: aload_3
/*     */     //   75: areturn
/*     */     //   76: aload_0
/*     */     //   77: invokespecial 188	com/zimbra/cs/mailclient/imap/ImapConnection:waitForResponse	()Lcom/zimbra/cs/mailclient/imap/ImapResponse;
/*     */     //   80: astore_2
/*     */     //   81: aload_2
/*     */     //   82: invokevirtual 189	com/zimbra/cs/mailclient/imap/ImapResponse:isTagged	()Z
/*     */     //   85: ifeq +12 -> 97
/*     */     //   88: aload_2
/*     */     //   89: astore_3
/*     */     //   90: aload_0
/*     */     //   91: aconst_null
/*     */     //   92: putfield 49	com/zimbra/cs/mailclient/imap/ImapConnection:request	Lcom/zimbra/cs/mailclient/imap/ImapRequest;
/*     */     //   95: aload_3
/*     */     //   96: areturn
/*     */     //   97: getstatic 190	com/zimbra/cs/mailclient/imap/ImapConnection:$assertionsDisabled	Z
/*     */     //   100: ifne +18 -> 118
/*     */     //   103: aload_2
/*     */     //   104: invokevirtual 191	com/zimbra/cs/mailclient/imap/ImapResponse:isContinuation	()Z
/*     */     //   107: ifne +11 -> 118
/*     */     //   110: new 192	java/lang/AssertionError
/*     */     //   113: dup
/*     */     //   114: invokespecial 193	java/lang/AssertionError:<init>	()V
/*     */     //   117: athrow
/*     */     //   118: aload_1
/*     */     //   119: invokevirtual 194	com/zimbra/cs/mailclient/imap/ImapRequest:isAuthenticate	()Z
/*     */     //   122: ifne +10 -> 132
/*     */     //   125: aload_1
/*     */     //   126: ldc -61
/*     */     //   128: invokevirtual 196	com/zimbra/cs/mailclient/imap/ImapRequest:failed	(Ljava/lang/String;)Lcom/zimbra/cs/mailclient/CommandFailedException;
/*     */     //   131: athrow
/*     */     //   132: aload_0
/*     */     //   133: aload_2
/*     */     //   134: invokevirtual 17	com/zimbra/cs/mailclient/imap/ImapResponse:getResponseText	()Lcom/zimbra/cs/mailclient/imap/ResponseText;
/*     */     //   137: invokevirtual 18	com/zimbra/cs/mailclient/imap/ResponseText:getText	()Ljava/lang/String;
/*     */     //   140: invokevirtual 197	com/zimbra/cs/mailclient/imap/ImapConnection:processContinuation	(Ljava/lang/String;)V
/*     */     //   143: goto -67 -> 76
/*     */     //   146: astore 4
/*     */     //   148: aload_0
/*     */     //   149: aconst_null
/*     */     //   150: putfield 49	com/zimbra/cs/mailclient/imap/ImapConnection:request	Lcom/zimbra/cs/mailclient/imap/ImapRequest;
/*     */     //   153: aload 4
/*     */     //   155: athrow
/*     */     // Line number table:
/*     */     //   Java source line #499	-> byte code offset #0
/*     */     //   Java source line #500	-> byte code offset #7
/*     */     //   Java source line #502	-> byte code offset #17
/*     */     //   Java source line #503	-> byte code offset #24
/*     */     //   Java source line #505	-> byte code offset #34
/*     */     //   Java source line #506	-> byte code offset #41
/*     */     //   Java source line #508	-> byte code offset #47
/*     */     //   Java source line #511	-> byte code offset #52
/*     */     //   Java source line #514	-> byte code offset #60
/*     */     //   Java source line #512	-> byte code offset #63
/*     */     //   Java source line #513	-> byte code offset #64
/*     */     //   Java source line #528	-> byte code offset #69
/*     */     //   Java source line #517	-> byte code offset #76
/*     */     //   Java source line #518	-> byte code offset #81
/*     */     //   Java source line #519	-> byte code offset #88
/*     */     //   Java source line #528	-> byte code offset #90
/*     */     //   Java source line #521	-> byte code offset #97
/*     */     //   Java source line #522	-> byte code offset #118
/*     */     //   Java source line #523	-> byte code offset #125
/*     */     //   Java source line #525	-> byte code offset #132
/*     */     //   Java source line #526	-> byte code offset #143
/*     */     //   Java source line #528	-> byte code offset #146
/*     */     // Local variable table:
/*     */     //   start	length	slot	name	signature
/*     */     //   0	156	0	this	ImapConnection
/*     */     //   0	156	1	req	ImapRequest
/*     */     //   63	2	2	e	LiteralException
/*     */     //   80	54	2	res	ImapResponse
/*     */     //   68	28	3	localImapResponse1	ImapResponse
/*     */     //   146	8	4	localObject	Object
/*     */     // Exception table:
/*     */     //   from	to	target	type
/*     */     //   52	60	63	com/zimbra/cs/mailclient/imap/ImapConnection$LiteralException
/*     */     //   52	69	146	finally
/*     */     //   76	90	146	finally
/*     */     //   97	148	146	finally
/*     */   }
/*     */   
/*     */   public synchronized boolean isIdling()
/*     */   {
/* 533 */     return (this.request != null) && (this.request.isIdle());
/*     */   }
/*     */   
/*     */   private ImapResponse sendIdle(ImapRequest req) {
/* 537 */     this.request = req;
/*     */     try {
/* 539 */       req.write(getImapOutputStream());
/* 540 */       ImapResponse res = waitForResponse();
/* 541 */       if (res.isTagged()) {
/* 542 */         return res;
/*     */       }
/* 544 */       assert (res.isContinuation());
/* 545 */       Thread t = new Thread(new Runnable()
/*     */       {
/*     */         public void run() {
/* 548 */           ImapConnection.this.idleHandler();
/*     */         }
/* 550 */       });
/* 551 */       t.setName("IMAP IDLE thread");
/* 552 */       t.setDaemon(true);
/* 553 */       t.start();
/*     */     } catch (IOException e) {
/* 555 */       this.request = null;
/*     */     }
/* 557 */     return null;
/*     */   }
/*     */   
/*     */   private void idleHandler() {
/*     */     try {
/* 562 */       ImapResponse res = waitForResponse();
/* 563 */       if (res.isContinuation()) {
/* 564 */         throw new IOException("Unexpected continuation response");
/*     */       }
/* 566 */       if ((!$assertionsDisabled) && (!res.isTagged())) throw new AssertionError();
/*     */     } catch (SocketTimeoutException e) {
/* 568 */       getLogger().debug("Timed-out during IDLE", e);
/*     */     } catch (IOException e) {
/* 570 */       if (!isClosed()) {
/* 571 */         getLogger().error("IDLE failed", e);
/*     */       }
/*     */     }
/* 574 */     synchronized (this) {
/* 575 */       this.request = null;
/* 576 */       notifyAll();
/*     */     }
/*     */   }
/*     */   
/*     */   public synchronized boolean stopIdle() throws IOException {
/* 581 */     if (isIdling()) {
/* 582 */       ImapOutputStream out = getImapOutputStream();
/* 583 */       out.writeLine("DONE");
/* 584 */       out.flush();
/* 585 */       long waitTime = (getImapConfig().getReadTimeout() > 0 ? getImapConfig().getReadTimeout() : 30) * 1000L;
/*     */       
/* 587 */       while (isIdling()) {
/* 588 */         long waitStart = System.currentTimeMillis();
/*     */         try {
/* 590 */           wait(waitTime);
/*     */         }
/*     */         catch (InterruptedException e) {}
/*     */         
/* 594 */         waitTime -= System.currentTimeMillis() - waitStart;
/* 595 */         if ((waitTime <= 0L) && (isIdling())) {
/* 596 */           close();
/* 597 */           return false;
/*     */         }
/*     */       }
/*     */     }
/* 601 */     return !isIdling();
/*     */   }
/*     */   
/*     */   private ImapOutputStream getImapOutputStream() {
/* 605 */     return (ImapOutputStream)this.mailOut;
/*     */   }
/*     */   
/*     */   void writeLiteral(Literal lit) throws IOException
/*     */   {
/* 610 */     boolean lp = (getImapConfig().isUseLiteralPlus()) && (hasCapability("LITERAL+"));
/*     */     
/* 612 */     ImapOutputStream out = (ImapOutputStream)this.mailOut;
/* 613 */     lit.writePrefix(out, lp);
/* 614 */     if (!lp) {
/* 615 */       out.flush();
/* 616 */       ImapResponse res = waitForResponse();
/* 617 */       if (!res.isContinuation()) {
/* 618 */         assert (res.isTagged());
/* 619 */         throw new LiteralException(res);
/*     */       }
/*     */     }
/* 622 */     lit.writeData(out);
/*     */   }
/*     */   
/*     */   public ImapConfig getImapConfig() {
/* 626 */     return (ImapConfig)this.config;
/*     */   }
/*     */   
/*     */   private static class LiteralException extends IOException {
/*     */     final ImapResponse res;
/*     */     
/*     */     LiteralException(ImapResponse res) {
/* 633 */       this.res = res;
/*     */     }
/*     */   }
/*     */   
/*     */   private boolean isShutdown() {
/* 638 */     return (isClosed()) || (isLogout());
/*     */   }
/*     */   
/*     */ 
/*     */   private ImapResponse waitForResponse()
/*     */     throws IOException
/*     */   {
/*     */     ImapResponse res;
/*     */     
/*     */     do
/*     */     {
/* 649 */       res = readResponse();
/* 650 */     } while (processResponse(res));
/* 651 */     return res;
/*     */   }
/*     */   
/*     */   private ImapResponse readResponse() throws IOException {
/*     */     try {
/* 656 */       return ImapResponse.read((ImapInputStream)this.mailIn);
/*     */     }
/*     */     catch (ParseException pe) {
/* 659 */       this.mailIn.readLine();
/* 660 */       this.mailIn.trace();
/* 661 */       throw pe;
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private synchronized boolean processResponse(ImapResponse res)
/*     */     throws IOException
/*     */   {
/* 672 */     if ((res.isUntagged()) && (res.isBAD())) {
/* 673 */       getLogger().error("Untagged BAD response: " + res);
/* 674 */       return true;
/*     */     }
/* 676 */     if ((res.isContinuation()) || ((res.isUntagged()) && (res.isBAD()))) {
/* 677 */       return false;
/*     */     }
/* 679 */     if (res.isUntagged()) {
/* 680 */       processUntagged(res);
/* 681 */       res.dispose();
/*     */     }
/*     */     
/* 684 */     if (res.isOK()) {
/* 685 */       ResponseText rt = res.getResponseText();
/* 686 */       Atom code = rt.getCode();
/* 687 */       if ((code != null) && (code.getCAtom() == CAtom.CAPABILITY)) {
/* 688 */         this.capabilities = ((ImapCapabilities)rt.getData());
/*     */       }
/* 690 */     } else if (res.getCCode() == CAtom.CAPABILITY) {
/* 691 */       this.capabilities = ((ImapCapabilities)res.getData());
/* 692 */     } else if ((this.mailbox != null) && (!this.request.isSelectOrExamine())) {
/* 693 */       this.mailbox.handleResponse(res);
/*     */     }
/* 695 */     return res.isUntagged();
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   private boolean processUntagged(ImapResponse res)
/*     */     throws IOException
/*     */   {
/* 703 */     ResponseHandler handler = this.request.getResponseHandler();
/* 704 */     if (handler != null) {
/*     */       try {
/* 706 */         handler.handleResponse(res);
/*     */       } catch (Throwable e) {
/* 708 */         throw new MailException("Exception in response handler", e);
/*     */       }
/*     */     }
/* 711 */     return false;
/*     */   }
/*     */   
/*     */   public String newTag() {
/* 715 */     Formatter fmt = new Formatter();
/* 716 */     fmt.format("C%02d", new Object[] { Integer.valueOf(this.tagCount.incrementAndGet()) });
/* 717 */     return fmt.toString();
/*     */   }
/*     */   
/*     */   public String toString()
/*     */   {
/* 722 */     return String.format("{host=%s,port=%d,type=%s,state=%s,folder=%s}", new Object[] { this.config.getHost(), Integer.valueOf(this.config.getPort()), this.config.getSecurity(), this.state, this.mailbox == null ? "null" : this.mailbox.getName() });
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/mailclient/imap/ImapConnection.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */